package com.djmw.mouse.service;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.djmw.mouse.entity.HrUser;
import com.djmw.mouse.entity.Position;
import com.djmw.mouse.entity.PositionHistory;
import com.djmw.mouse.repository.PositionDao;
import com.djmw.mouse.repository.PositionHistoryDao;

//Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional(readOnly = true)
public class PositionService {

    @Autowired
    private PositionDao positionDao;
    @Autowired
    private PositionHistoryDao positionHistoryDao;

    public Position getPosition(Long id) {
        return positionDao.findOne(id);
    }

    @Transactional(readOnly = false)
    public void savePosition(Position entity, HrUser hrUser) {
        positionDao.save(entity);
        if (hrUser != null) {
            PositionHistory history = new PositionHistory(entity, hrUser, new Date());
            positionHistoryDao.save(history);
        }
    }

    @Transactional(readOnly = false)
    public void deletePosition(Long id, HrUser hrUser) {
        positionDao.changeStatus(id, Position.STATUS_DELETED);
        saveHistory(id, hrUser, new Date());
    }

    @Transactional(readOnly = false)
    public void enablePosition(Long id, HrUser hrUser) {
        positionDao.changeStatus(id, Position.STATUS_ENABLED);
        saveHistory(id, hrUser, new Date());
    }

    @Transactional(readOnly = false)
    public void disablePosition(Long id, HrUser hrUser) {
        positionDao.changeStatus(id, Position.STATUS_DISABLED);
        saveHistory(id, hrUser, new Date());
    }

    private void saveHistory(Long positionId, HrUser hrUser, Date datetime) {
        Position entity = positionDao.findOne(positionId);
        PositionHistory history = new PositionHistory(entity, hrUser, new Date());
        positionHistoryDao.save(history);
    }

    public Page<Position> getPosition(Map<String, Object> searchParams, int pageNumber, int pageSize, String sortType,
            String sortDir) {
        PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, sortType, sortDir);
        Specification<Position> spec = buildSpecification(searchParams);
        return positionDao.findAll(spec, pageRequest);
    }

    public Page<Position> getCompanyPosition(Long companyId, Map<String, Object> searchParams, int pageNumber,
            int pageSize, String sortType, String sortDir) {
        return getCompanyPosition(companyId, searchParams, pageNumber, pageSize, sortType, sortDir, false);
    }

    public Page<Position> getCompanyPosition(Long companyId, Map<String, Object> searchParams, int pageNumber,
            int pageSize, String sortType, String sortDir, boolean includeDeletedPosition) {
        PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, sortType, sortDir);
        Specification<Position> spec = buildCompanySpecification(companyId, searchParams, includeDeletedPosition);

        return positionDao.findAll(spec, pageRequest);
    }

	                                                            /**
     * 创建分页请求.
     */
     private PageRequest buildPageRequest(int pageNumber, int pagzSize, String sortType, String sortDir) {
         Sort sort = null;
         if ("auto".equals(sortType)) {
             sort = new Sort(Direction.DESC, "id");
         } else {
             sort = new Sort("d".equalsIgnoreCase(sortDir) ? Direction.DESC : Direction.ASC, sortType);
         }

         return new PageRequest(pageNumber - 1, pagzSize, sort);
     }

     /**
     * 创建动态查询条件组合.
     */
     private Specification<Position> buildSpecification(Map<String, Object> searchParams) {
        Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
         Specification<Position> spec = DynamicSpecifications.bySearchFilter(filters.values(), Position.class);
         return spec;
     }

     private Specification<Position> buildCompanySpecification(Long companyId, Map<String, Object> searchParams,
             boolean includeDeletedPosition) {
        Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
         filters.put("company.id", new SearchFilter("company.id", Operator.EQ, companyId));
         if (!includeDeletedPosition) {
             // TODO: Is this correct? NO "NEQ" in Operator?
             filters.put("status", new SearchFilter("status", Operator.LT, Position.STATUS_DELETED));
         }
         Specification<Position> spec = DynamicSpecifications.bySearchFilter(filters.values(), Position.class);
         return spec;
     }

     @Transactional(readOnly = false)
     public void refresh(Long id, HrUser hrUser) {
         Date refreshDate = new Date();
         Date closeDate = DateUtils.addMonths(refreshDate, 2);
         positionDao.refresh(id, refreshDate, closeDate);
         saveHistory(id, hrUser, refreshDate);
     }

     @Transactional(readOnly = false)
     public void copyPosition(Long id, HrUser hrUser) {
         Position pos = positionDao.findOne(id);
         Position position = new Position(pos);
         position.setId(null);
         Date now = new Date();
         position.setPublishDate(now);
         position.setRefreshDate(now);
         position.setCloseDate(DateUtils.addMonths(now, 2));
         position.setStatus(Position.STATUS_ENABLED);
         positionDao.save(position);
         PositionHistory history = new PositionHistory(position, hrUser, now);
         positionHistoryDao.save(history);
     }

}
